<!--
 * @Description:
 * @version:
 * @Author: 尹鹏孝
 * @Date: 2023-03-01 13:50:34
 * @LastEditors: 尹鹏孝
 * @LastEditTime: 2023-03-01 17:27:58
-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="gb2312">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>javascript 对象</title>
</head>
<body>
    <script>
        //  "use strict";
        // 文字法
        var myObj={
            key:'value'
        };
        //构造函数法
        var myObj = new Object();
        myObj.key=1222;
        //javascript万物皆对象，的观点进行解释和评价。javascript的类型基本类型：string，number，null,undefined,boolean,
        // 复杂类型object，Date,RegExp,Error,Number,Function,Map,Set,Symbol,String,Boolean,Array,
        // typeof null==="object"的原因：因为底层的javascript都是二进制，在javascript判断类型中前三位是0会被判断为object,null前三位都是0所以就会是object，这是javascript的一个bug。
        // 对象的计算属性和属性访问器，.语法后的名称必须是符合javascript标识符命名的，而[...]是符合...为一字符的变量或者字符本身就行，好处是更加灵活可拓展
        // 函数和方法在javascript 对象中会出现方法和函数互换，本质都是引用一个函数的指针。
        // 数组===============
        // 1、数组可以追加一个属性，还可以给数组追加一个字符串数字来改变数组的长度

        var myArray=["foo","42","bar"];
        myArray[100]=111;
        console.log(myArray);
        //对象复制
        // 深复制、浅复制
        // JSON序列化一个对象，object.assign(对象，要复制的对象列表，)=>浅复制，会遍历对象的可枚举属性然后进行赋值复制。
        //javascript的描述符
        var myObject={
            a:2
        }

       let ab= Object.getOwnPropertyDescriptor(myObject,"a");
       let bc= Object.getOwnPropertyDescriptor(myObj,"key");

       console.log(ab);
       console.log(bc);

       var myObjectTs={};
       Object.defineProperty(myObjectTs,"a",{
        value:2,
        writable:true,
        configurable:true,
        enumerable:true
       });

       console.log(myObjectTs.a);


       var lk={};
       Object.defineProperty(lk,"a",{
        value:2,
        writable:false,
        configurable:false,
        enumerable:true
       });
       lk.a=34

       //Configurable 只要属性是Configurable （可配置的）就可以使用defineProperty方法进行描述。不管是严格还是宽松模式尝试修改configurable都会报错TypeError。
       //修改configurable是单向操作无法改成其true，当把configurable改成false还可以把writable改为false，但是无法把他由false改为true，删除configurable也不行

       //设置可枚举，enumerable,设置为true就可以在for in里遍历出来

       let yyds = {
        "mmp":"mmp"
       }
       Object.defineProperty(yyds,"nyd",{
        value:123,
        enumerable:false
       });
       console.log(yyds)
       for(let k in yyds){
        console.log(k);
       };
       console.log(yyds.nyd);
       yyds.nyd=12333;
        console.log(yyds.nyd);

        // 对象的不变性设置可修改writable\configurable可配置false在当前对象下的属性是不可修改的。但是子属性是可以修改的。
        //还可以设置对象的可拓展属性PreventExtensions.
        var myObjectKeys = {
            a:999
        }
        Object.preventExtensions(myObjectKeys)
        myObjectKeys.a=11111;
          myObjectKeys.aFix = 11111;
        console.log(myObjectKeys);

        //密封属性
       let freeze=  Object.freeze({
            a:12355555,
        })
        freeze.a=4444;

         let seal = Object.seal({
                a: 123,
            })
            seal.a=12333;

             console.log("冻结和密封");
        //冻结
        console.log(freeze);

        //密封
        console.log(seal);

        var getter={
            a:undefined
        }
        console.log(getter.a);

        console.log(getter.b);


        var anObject={
            get a(){
                return 2;
            }
        }

        Object.defineProperty(anObject,"b",{
            get:function(){
                return this.a*2;
            },
            enumerable:true,
        })

        anObject.a=2;
        console.log(anObject.b);

        var tenantId = {
            get a(){
                return this._m_;
            },
            set a(val){
                this._m_=val*200;
            }
        }

        tenantId.a=2;
        console.log(tenantId.a)


        // 判断一个属性是否存在对象上的方法
        console.log('a' in tenantId);
        console.log(tenantId.hasOwnProperty("a"));
        console.log(Object.prototype.hasOwnProperty.call(tenantId,"a"));
        // 对象属性是否可枚举
        Object.keys(tenantId)//返回当前对象所有可枚举key为一个数组。
        Object.getOwnPropertyNames(tenantId);//返回当前对象的所有属性不论是否可枚举
        // keys和getOwnPropertyNames都只会查找当前对象的直接包含属性

        //可迭代对象for ...of...。

        var kks={
            a:111,
            b:1233,
            *[Symbol.iterator](){
                for(let key in this){
                    yield[key,this[key]]
                }
            }
        };

        for(let [key,value] of kks){
            console.log(key+"->",value);
        }





    </script>
</body>
</html>